import json
import os
from pathlib import Path

from pyVim.connect import SmartConnect, Disconnect
from pyVmomi import vim
import ssl
import atexit
import sys



class VCenterManager:
    def __init__(self):
        self.service_instance = None
        self.content = None
        self.selected_host = None
        self.selected_datastore = None
        self.selected_network = None
        self.selected_resource_pool = None
        self.selected_folder = None
        self.selected_vm = None

    def connect(self, host, user, password, port=443):
        """连接到vCenter服务器"""
        context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
        context.verify_mode = ssl.CERT_NONE

        try:
            self.service_instance = SmartConnect(
                host=host,
                user=user,
                pwd=password,
                port=port,
                sslContext=context
            )
            atexit.register(Disconnect, self.service_instance)
            self.content = self.service_instance.RetrieveContent()
            print("成功连接到vCenter")
            return True
        except Exception as e:
            print(f"连接失败: {str(e)}")
            return False

    def show_menu(self, title, options):
        """显示交互菜单"""
        print(f"\n{title}")
        print("=" * 50)
        for i, option in enumerate(options, 1):
            print(f"{i}. {option['name']}")
        print("0. 返回主菜单")

        while True:
            try:
                choice = int(input("请选择: "))
                if 0 <= choice <= len(options):
                    return choice
                print("无效选择，请重新输入")
            except ValueError:
                print("请输入数字")

    def select_datacenter(self):
        """选择数据中心"""
        datacenters = self.content.rootFolder.childEntity
        options = [{'name': dc.name, 'object': dc} for dc in datacenters if isinstance(dc, vim.Datacenter)]
        choice = self.show_menu("选择数据中心", options)
        return options[choice - 1]['object'] if choice > 0 else None

    def select_cluster(self, datacenter):
        """选择集群"""
        clusters = []
        for folder in datacenter.hostFolder.childEntity:
            if isinstance(folder, vim.ClusterComputeResource):
                clusters.append(folder)
            elif isinstance(folder, vim.Folder):
                clusters.extend([c for c in folder.childEntity if isinstance(c, vim.ClusterComputeResource)])

        options = [{'name': c.name, 'object': c} for c in clusters]
        choice = self.show_menu("选择集群", options)
        return options[choice - 1]['object'] if choice > 0 else None

    def select_host(self, cluster):
        """选择主机"""
        # 获取所有主机
        hosts = cluster.host

        # 为每个主机准备显示信息
        options = []
        for host in hosts:
            # 获取主机资源信息
            host_resources = self.get_host_resources(host)

            # 获取主机数据存储信息
            datastore_info = []
            for ds in host.datastore:
                ds_space = self.get_datastore_space(ds)
                datastore_info.append(f"{ds.name}: 可用 {ds_space['free_gb']:.1f} GB")

            # 格式化显示信息
            display_name = (
                f"{host.name} | "
                f"CPU: 已用 <= {host_resources['cpu_available']:.1f}Ghz /共{host_resources['cpu_total']}核 | "
                f"内存: 可用 {host_resources['mem_available_mb'] / 1024:.1f} GB / 总内存 {host_resources['mem_total_mb'] / 1024:.1f} GB | "
                f"存储: {', '.join(datastore_info[:2])}"  # 只显示前两个数据存储，避免太长
            )

            options.append({
                'name': display_name,
                'object': host,
                'resources': host_resources
            })

        # 显示菜单
        choice = self.show_menu("选择主机 (CPU可用/总 | 内存可用/总 | 存储可用)", options)

        if choice > 0:
            self.selected_host = options[choice - 1]['object']
            return self.selected_host
        return None

    def select_vm(self, datacenter):
        """选择虚拟机"""
        vms = []

        def traverse(folder):
            for child in folder.childEntity:
                if isinstance(child, vim.VirtualMachine):
                    vms.append(child)
                elif isinstance(child, vim.Folder):
                    traverse(child)

        traverse(datacenter.vmFolder)

        options = [{'name': vm.name, 'object': vm} for vm in vms]
        choice = self.show_menu("选择虚拟机", options)
        if choice > 0:
            self.selected_vm = options[choice - 1]['object']
            return self.selected_vm
        return None

    def get_host_resources(self, host):
        """获取主机可用资源"""
        stats = {}
        cpu_total = host.hardware.cpuInfo.numCpuThreads
        cpu_usage_percent = host.summary.quickStats.overallCpuUsage
        cpu_available = max(1, cpu_total - (cpu_total * cpu_usage_percent / 100))

        mem_total = host.hardware.memorySize / (1024 * 1024)
        mem_usage = host.summary.quickStats.overallMemoryUsage

        stats['cpu_total'] = cpu_total
        stats['cpu_available'] = cpu_available
        stats['mem_total_mb'] = mem_total
        stats['mem_available_mb'] = max(1024, mem_total - mem_usage)

        return stats

    def get_datastore_space(self, datastore):
        """获取数据存储可用空间"""
        free_space = datastore.summary.freeSpace / (1024 * 1024 * 1024)
        capacity = datastore.summary.capacity / (1024 * 1024 * 1024)
        return {
            'free_gb': free_space,
            'total_gb': capacity
        }

    def input_with_range(self, prompt, min_val, max_val, default=None, unit=""):
        """带范围检查的输入"""
        while True:
            try:
                if default is not None:
                    prompt += f" ({min_val}-{max_val}{unit}, 默认: {default}{unit}): "
                else:
                    prompt += f" ({min_val}-{max_val}{unit}): "

                value = input(prompt)
                if not value and default is not None:
                    return default

                value = float(value)
                if min_val <= value <= max_val:
                    return value
                print(f"输入必须在 {min_val}-{max_val}{unit} 之间")
            except ValueError:
                print("请输入有效的数字")

    def select_datastore(self, host):
        """选择数据存储"""
        datastores = host.datastore
        options = []
        for ds in datastores:
            ds_space = self.get_datastore_space(ds)
            options.append({
                'name': f"{ds.name} ({ds_space['free_gb']:.1f}GB 可用，共 {ds_space['total_gb']:.1f}GB)",
                'object': ds,
                'space': ds_space
            })
        choice = self.show_menu(f"选择数据存储 (主机: {host.name})", options)
        if choice > 0:
            self.selected_datastore = options[choice - 1]['object']
            return self.selected_datastore
        return None

    def select_network(self, host):
        """选择网络"""
        networks = host.network
        options = []
        for net in networks:
            if isinstance(net, vim.Network):
                options.append({
                    'name': f"{net.name} (标准交换机)",
                    'object': net
                })
            elif isinstance(net, vim.dvs.DistributedVirtualPortgroup):
                options.append({
                    'name': f"{net.name} (分布式端口组)",
                    'object': net
                })
        choice = self.show_menu(f"选择网络 (主机: {host.name})", options)
        if choice > 0:
            self.selected_network = options[choice - 1]['object']
            return self.selected_network
        return None

    def select_resource_pool(self, host):
        """选择资源池"""
        resource_pools = []

        def traverse_pools(pool, indent=0):
            resource_pools.append({
                'name': "  " * indent + pool.name,
                'object': pool
            })
            for child in pool.resourcePool:
                traverse_pools(child, indent + 1)

        traverse_pools(host.parent.resourcePool)
        choice = self.show_menu(f"选择资源池 (主机: {host.name})", resource_pools)
        if choice > 0:
            self.selected_resource_pool = resource_pools[choice - 1]['object']
            return self.selected_resource_pool
        return None

    def select_folder(self, datacenter):
        """选择虚拟机文件夹"""
        folders = []

        def traverse(folder, indent=0):
            folders.append({'name': "  " * indent + folder.name, 'object': folder})
            for child in folder.childEntity:
                if isinstance(child, vim.Folder):
                    traverse(child, indent + 1)

        traverse(datacenter.vmFolder)
        choice = self.show_menu("选择虚拟机文件夹", folders)
        if choice > 0:
            self.selected_folder = folders[choice - 1]['object']
            return self.selected_folder
        return None

    def create_scsi_controller(self):
        """创建SCSI控制器"""
        scsi_spec = vim.vm.device.VirtualDeviceSpec()
        scsi_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add
        scsi_spec.device = vim.vm.device.ParaVirtualSCSIController()
        scsi_spec.device.key = 1000
        scsi_spec.device.busNumber = 0
        scsi_spec.device.sharedBus = "noSharing"
        scsi_spec.device.scsiCtlrUnitNumber = 7
        return scsi_spec

    def create_virtual_disk(self, datastore, vm_name, size_gb, controller_key=1000, unit_number=None):
        """创建虚拟磁盘配置"""
        disk_spec = vim.vm.device.VirtualDeviceSpec()
        disk_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add
        disk_spec.fileOperation = vim.vm.device.VirtualDeviceSpec.FileOperation.create

        # 创建磁盘设备
        disk_spec.device = vim.vm.device.VirtualDisk()
        disk_spec.device.key = -1  # 系统会自动分配

        # 设置控制器key
        disk_spec.device.controllerKey = controller_key

        # 设置单元号（确保不是7，因为7是SCSI控制器保留的）
        if unit_number is None:
            unit_number = self.get_next_unit_number(self.selected_vm)
        disk_spec.device.unitNumber = unit_number

        # 设置磁盘大小（最小1GB）
        size_kb = int(max(1, size_gb) * 1024 * 1024)
        disk_spec.device.capacityInKB = size_kb

        # 设置磁盘模式
        disk_spec.device.backing = vim.vm.device.VirtualDisk.FlatVer2BackingInfo()
        disk_spec.device.backing.diskMode = 'persistent'
        disk_spec.device.backing.thinProvisioned = True

        # 设置磁盘文件名
        disk_spec.device.backing.fileName = f"[{datastore.name}] {vm_name}/{vm_name}_disk{unit_number}.vmdk"

        return disk_spec

    def get_disk_controller(self, vm):
        """获取可用的SCSI控制器"""
        for dev in vm.config.hardware.device:
            if isinstance(dev, vim.vm.device.VirtualSCSIController):
                return dev.key
        raise Exception("未找到可用的SCSI控制器")

    def get_next_unit_number(self, vm):
        """获取下一个可用的单元号"""
        used_numbers = set()
        for dev in vm.config.hardware.device:
            if hasattr(dev, 'unitNumber'):
                used_numbers.add(dev.unitNumber)

        for i in range(0, 16):
            if i not in used_numbers and i != 7:  # 单元号7保留给SCSI控制器
                return i
        raise Exception("没有可用的单元号")

    def create_network_adapter(self, network):
        """创建网络适配器配置"""
        nic_spec = vim.vm.device.VirtualDeviceSpec()
        nic_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add

        nic_spec.device = vim.vm.device.VirtualVmxnet3()
        nic_spec.device.key = -1  # 系统会自动分配
        nic_spec.device.backing = vim.vm.device.VirtualEthernetCard.NetworkBackingInfo()

        if isinstance(network, vim.Network):
            nic_spec.device.backing.network = network
            nic_spec.device.backing.deviceName = network.name
        elif isinstance(network, vim.dvs.DDistributedVirtualPortgroup):
            nic_spec.device.backing.port = vim.dvs.PortConnection()
            nic_spec.device.backing.port.portgroupKey = network.key
            nic_spec.device.backing.port.switchUuid = network.config.distributedVirtualSwitch.uuid

        nic_spec.device.connectable = vim.vm.device.VirtualDevice.ConnectInfo()
        nic_spec.device.connectable.startConnected = True
        nic_spec.device.connectable.allowGuestControl = True
        return nic_spec

    def select_guest_os(self):
        """选择客户机操作系统类型和版本"""
        # 操作系统家族选项
        os_families = [
            {'name': 'Windows', 'value': 'windowsGuest'},
            {'name': 'Linux', 'value': 'linuxGuest'},
            {'name': '其他', 'value': 'otherGuestFamily'}
        ]

        # 显示操作系统家族菜单
        print("\n=== 选择操作系统 ===")
        for i, family in enumerate(os_families, 1):
            print(f"{i}. {family['name']}")

        while True:
            try:
                choice = int(input("请选择操作系统 (1-3): "))
                if 1 <= choice <= 3:
                    selected_family = os_families[choice - 1]
                    break
                print("请输入1-3之间的数字")
            except ValueError:
                print("请输入有效的数字")

        # 根据选择的家族显示具体版本
        os_versions = []

        if selected_family['value'] == 'windowsGuest':
            os_versions = [
                {"name": "Microsoft Windows Server 2016 (64 位)", "value": "windows9Server64Guest"},
                {"name": "Microsoft Windows Server 2012 (64 位)", "value": "windows8Server64Guest"},
                {"name": "Microsoft Windows Server 2008 R2 (64 位)", "value": "windows7Server64Guest"},
                {"name": "Microsoft Windows Server 2008 (64 位)", "value": "winLonghorn64Guest"},
                {"name": "Microsoft Windows Server 2008 (32 位)", "value": "winLonghornGuest"},
                {"name": "Microsoft Windows Server 2003 (64 位)", "value": "winNetEnterprise64Guest"},
                {"name": "Microsoft Windows Server 2003 (32 位)", "value": "winNetEnterpriseGuest"},
                {"name": "Microsoft Windows 10 (64 位)", "value": "windows9_64Guest"},
                {"name": "Microsoft Windows 10 (32 位)", "value": "windows9Guest"},
                {"name": "Microsoft Windows 8.x (64 位)", "value": "windows8_64Guest"},
                {"name": "Microsoft Windows 8.x (32 位)", "value": "windows8Guest"},
                {"name": "Microsoft Windows 7 (64 位)", "value": "windows7_64Guest"},
                {"name": "Microsoft Windows 7 (32 位)", "value": "windows7Guest"},
                {"name": "Microsoft Windows Vista (64 位)", "value": "winVista64Guest"},
                {"name": "Microsoft Windows Vista (32 位)", "value": "winVistaGuest"},
                {"name": "Microsoft Windows XP Professional (64 位)", "value": "winXPPro64Guest"},
                {"name": "Microsoft Windows XP Professional (32 位)", "value": "winXPProGuest"},
                {"name": "Microsoft Windows 2000", "value": "win2000AdvServGuest"},
                {"name": "Microsoft Windows NT", "value": "winNTGuest"},
                {"name": "Microsoft Windows 98", "value": "win98Guest"},
                {"name": "Microsoft Windows 95", "value": "win95Guest"},
                {"name": "Microsoft Windows 3.1", "value": "win31Guest"},
                {"name": "Microsoft MS-DOS", "value": "dosGuest"}
            ]
        elif selected_family['value'] == 'linuxGuest':
            os_versions = [
                {"name": "Amazon Linux 2 (64 位)", "value": "amazonlinux2_64Guest"},
                {"name": "VMware Photon OS (64 位)", "value": "vmwarePhoton64Guest"},
                {"name": "Red Hat Enterprise Linux 8 (64 位)", "value": "rhel8_64Guest"},
                {"name": "Red Hat Enterprise Linux 7 (64 位)", "value": "rhel7_64Guest"},
                {"name": "Red Hat Enterprise Linux 6 (64 位)", "value": "rhel6_64Guest"},
                {"name": "Red Hat Enterprise Linux 6 (32 位)", "value": "rhel6Guest"},
                {"name": "Red Hat Enterprise Linux 5 (64 位)", "value": "rhel5_64Guest"},
                {"name": "Red Hat Enterprise Linux 5 (32 位)", "value": "rhel5Guest"},
                {"name": "Red Hat Enterprise Linux 4 (64 位)", "value": "rhel4_64Guest"},
                {"name": "Red Hat Enterprise Linux 4 (32 位)", "value": "rhel4Guest"},
                {"name": "Red Hat Enterprise Linux 3 (64 位)", "value": "rhel3_64Guest"},
                {"name": "Red Hat Enterprise Linux 3 (32 位)", "value": "rhel3Guest"},
                {"name": "Red Hat Enterprise Linux 2.1", "value": "rhel2Guest"},
                {"name": "SUSE Linux Enterprise 15 (64 位)", "value": "sles15_64Guest"},
                {"name": "SUSE Linux Enterprise 12 (64 位)", "value": "sles12_64Guest"},
                {"name": "SUSE Linux Enterprise 11 (64 位)", "value": "sles11_64Guest"},
                {"name": "SUSE Linux Enterprise 11 (32 位)", "value": "sles11Guest"},
                {"name": "SUSE Linux Enterprise 10 (64 位)", "value": "sles10_64Guest"},
                {"name": "SUSE Linux Enterprise 10 (32 位)", "value": "sles10Guest"},
                {"name": "SUSE Linux Enterprise 8/9 (64 位)", "value": "sles64Guest"},
                {"name": "SUSE Linux Enterprise 8/9 (32 位)", "value": "slesGuest"},
                {"name": "CentOS 8 (64 位)", "value": "centos8_64Guest"},
                {"name": "CentOS 7 (64 位)", "value": "centos7_64Guest"},
                {"name": "CentOS 6 (64 位)", "value": "centos6_64Guest"},
                {"name": "CentOS 6 (32 位)", "value": "centos6Guest"},
                {"name": "CentOS 4/5 或更高版本 (64 位)", "value": "centos64Guest"},
                {"name": "CentOS 4/5 或更高版本 (32 位)", "value": "centosGuest"},
                {"name": "Debian GNU/Linux 10 (64 位)", "value": "debian10_64Guest"},
                {"name": "Debian GNU/Linux 10 (32 位)", "value": "debian10Guest"},
                {"name": "Debian GNU/Linux 9 (64 位)", "value": "debian9_64Guest"},
                {"name": "Debian GNU/Linux 9 (32 位)", "value": "debian9Guest"},
                {"name": "Debian GNU/Linux 8 (64 位)", "value": "debian8_64Guest"},
                {"name": "Debian GNU/Linux 8 (32 位)", "value": "debian8Guest"},
                {"name": "Debian GNU/Linux 7 (64 位)", "value": "debian7_64Guest"},
                {"name": "Debian GNU/Linux 7 (32 位)", "value": "debian7Guest"},
                {"name": "Debian GNU/Linux 6 (64 位)", "value": "debian6_64Guest"},
                {"name": "Debian GNU/Linux 6 (32 位)", "value": "debian6Guest"},
                {"name": "Debian GNU/Linux 5 (64 位)", "value": "debian5_64Guest"},
                {"name": "Debian GNU/Linux 5 (32 位)", "value": "debian5Guest"},
                {"name": "Debian GNU/Linux 4 (64 位)", "value": "debian4_64Guest"},
                {"name": "Debian GNU/Linux 4 (32 位)", "value": "debian4Guest"},
                {"name": "SUSE openSUSE (64 位)", "value": "opensuse64Guest"},
                {"name": "SUSE openSUSE (32 位)", "value": "opensuseGuest"},
                {"name": "Asianux 8 (64 位)", "value": "asianux8_64Guest"},
                {"name": "Asianux 7 (64 位)", "value": "asianux7_64Guest"},
                {"name": "Asianux 4 (64 位)", "value": "asianux4_64Guest"},
                {"name": "Asianux 4 (32 位)", "value": "asianux4Guest"},
                {"name": "Asianux 3 (64 位)", "value": "asianux3_64Guest"},
                {"name": "Asianux 3 (32 位)", "value": "asianux3Guest"},
                {"name": "Red Hat Fedora (64 位)", "value": "fedora64Guest"},
                {"name": "Red Hat Fedora (32 位)", "value": "fedoraGuest"},
                {"name": "Oracle Linux 8 (64 位)", "value": "oracleLinux8_64Guest"},
                {"name": "Oracle Linux 7 (64 位)", "value": "oracleLinux7_64Guest"},
                {"name": "Oracle Linux 6 (64 位)", "value": "oracleLinux6_64Guest"},
                {"name": "Oracle Linux 6 (32 位)", "value": "oracleLinux6Guest"},
                {"name": "Oracle Linux 4/5 或更高版本 (64 位)", "value": "oracleLinux64Guest"},
                {"name": "Oracle Linux 4/5 或更高版本 (32 位)", "value": "oracleLinuxGuest"},
                {"name": "Ubuntu Linux (64 位)", "value": "ubuntu64Guest"},
                {"name": "Ubuntu Linux (32 位)", "value": "ubuntuGuest"},
                {"name": "CoreOS Linux (64 位)", "value": "coreos64Guest"},
                {"name": "其他 4.x 或更高版本的 Linux (64 位)", "value": "other4xLinux64Guest"},
                {"name": "其他 4.x 或更高版本的 Linux (32 位)", "value": "other4xLinuxGuest"},
                {"name": "其他 3.x Linux (64 位)", "value": "other3xLinux64Guest"},
                {"name": "其他 3.x Linux (32 位)", "value": "other3xLinuxGuest"},
                {"name": "其他 2.6.x Linux (64 位)", "value": "other26xLinux64Guest"},
                {"name": "其他 2.6.x Linux (32 位)", "value": "other26xLinuxGuest"},
                {"name": "其他 2.4.x Linux (64 位)", "value": "other24xLinux64Guest"},
                {"name": "其他 2.4.x Linux (32 位)", "value": "other24xLinuxGuest"},
                {"name": "其他 Linux (64 位)", "value": "otherLinux64Guest"},
                {"name": "其他 Linux (32 位)", "value": "otherLinuxGuest"}
            ]
        else:
            os_versions = [
                {"name": "Apple macOS 10.14 (64 位)", "value": "darwin18_64Guest"},
                {"name": "Apple macOS 10.13 (64 位)", "value": "darwin17_64Guest"},
                {"name": "Apple Mac OS X 10.12 (64 位)", "value": "darwin16_64Guest"},
                {"name": "Apple Mac OS X 10.11 (64 位)", "value": "darwin15_64Guest"},
                {"name": "Apple Mac OS X 10.10 (64 位)", "value": "darwin14_64Guest"},
                {"name": "Apple Mac OS X 10.9 (64 位)", "value": "darwin13_64Guest"},
                {"name": "Apple Mac OS X 10.8 (64 位)", "value": "darwin12_64Guest"},
                {"name": "Apple Mac OS X 10.7 (64 位)", "value": "darwin11_64Guest"},
                {"name": "Apple Mac OS X 10.7 (32 位)", "value": "darwin11Guest"},
                {"name": "Apple Mac OS X 10.6 (64 位)", "value": "darwin10_64Guest"},
                {"name": "Apple Mac OS X 10.6 (32 位)", "value": "darwin10Guest"},
                {"name": "FreeBSD 12 或更高版本 (64 位)", "value": "freebsd12_64Guest"},
                {"name": "FreeBSD 12 或更高版本 (32 位)", "value": "freebsd12Guest"},
                {"name": "FreeBSD 11 (64 位)", "value": "freebsd11_64Guest"},
                {"name": "FreeBSD 11 (32 位)", "value": "freebsd11Guest"},
                {"name": "FreeBSD Pre-11 版本 (64 位)", "value": "freebsd64Guest"},
                {"name": "FreeBSD Pre-11 版本 (32 位)", "value": "freebsdGuest"},
                {"name": "IBM OS/2", "value": "os2Guest"},
                {"name": "Novell NetWare 6.x", "value": "netware6Guest"},
                {"name": "Novell NetWare 5.1", "value": "netware5Guest"},
                {"name": "Oracle Solaris 11 (64 位)", "value": "solaris11_64Guest"},
                {"name": "Oracle Solaris 10 (64 位)", "value": "solaris10_64Guest"},
                {"name": "Oracle Solaris 10 (32 位)", "value": "solaris10Guest"},
                {"name": "Sun Microsystems Solaris 9", "value": "solaris9Guest"},
                {"name": "Sun Microsystems Solaris 8", "value": "solaris8Guest"},
                {"name": "SCO OpenServer 6", "value": "openServer6Guest"},
                {"name": "SCO OpenServer 5", "value": "openServer5Guest"},
                {"name": "SCO UnixWare 7", "value": "unixWare7Guest"},
                {"name": "Serenity Systems eComStation 2", "value": "eComStation2Guest"},
                {"name": "Serenity Systems eComStation 1", "value": "eComStationGuest"},
                {"name": "其他 (64 位)", "value": "otherGuest64"},
                {"name": "其他 (32 位)", "value": "otherGuest"},
                {"name": "VMware ESXi 6.5 或更高版本", "value": "vmkernel65Guest"},
                {"name": "VMware ESXi 6.0", "value": "vmkernel6Guest"},
                {"name": "VMware ESXi 5.x", "value": "vmkernel5Guest"},
                {"name": "VMware ESX 4.x", "value": "vmkernelGuest"}
            ]

        # 显示操作系统版本菜单
        print(f"\n=== 选择 {selected_family['name']} 版本 ===")
        for i, version in enumerate(os_versions, 1):
            print(f"{i}. {version['name']}")

        while True:
            try:
                choice = int(input(f"请选择 {selected_family['name']} 版本 (1-{len(os_versions)}): "))
                if 1 <= choice <= len(os_versions):
                    selected_version = os_versions[choice - 1]
                    break
                print(f"请输入1-{len(os_versions)}之间的数字")
            except ValueError:
                print("请输入有效的数字")

        print(f"\n已选择: {selected_family['name']} - {selected_version['name']}")
        return selected_version['value']

    def input_memory_with_unit(self, min_val, max_val, default=None, unit=""):
        """带单位选择的内存输入"""
        while True:
            try:
                unit = input("选择内存单位 (1=MB, 2=GB, 默认:1): ").strip() or "1"
                if unit not in ["1", "2"]:
                    print("请选择1或2")
                    continue

                is_gb = (unit == "2")
                unit_str = "GB" if is_gb else "MB"
                min_val_unit = min_val / 1024 if is_gb else min_val
                max_val_unit = max_val / 1024 if is_gb else max_val

                if default is not None:
                    default_unit = default / 1024 if is_gb else default
                    prompt = f"输入内存大小 ({min_val_unit:.1f}-{max_val_unit:.1f}{unit_str}, 默认:{default_unit:.1f}{unit_str}): "
                else:
                    prompt = f"输入内存大小 ({min_val_unit:.1f}-{max_val_unit:.1f}{unit_str}): "

                value = input(prompt)
                if not value and default is not None:
                    return default

                value = float(value)
                if is_gb:
                    value_mb = value * 1024
                else:
                    value_mb = value

                if min_val <= value_mb <= max_val:
                    return int(value_mb)

                print(f"输入必须在 {min_val_unit:.1f}-{max_val_unit:.1f}{unit_str} 之间")
            except ValueError:
                print("请输入有效的数字")

    def create_vm_interactive(self):
        """交互式创建虚拟机"""
        print("\n=== 创建虚拟机向导 ===")
        vm_name = input("输入虚拟机名称: ").strip()
        if not vm_name:
            print("虚拟机名称不能为空")
            return

        # 选择操作系统
        guest_id = self.select_guest_os()

        datacenter = self.select_datacenter()
        if not datacenter:
            return

        cluster = self.select_cluster(datacenter)
        if not cluster:
            return

        host = self.select_host(cluster)
        if not host:
            return

        host_resources = self.get_host_resources(host)

        print(f"\n主机 {host.name} CPU信息:")
        print(
            f"  总逻辑CPU核心: {host_resources['cpu_total']} 核, " + f"已使用率: {host.summary.quickStats.overallCpuUsage / 1000:.2f}GHz")

        cpu_count = int(self.input_with_range(
            "输入CPU核心数",
            1,
            host.hardware.cpuInfo.numCpuThreads,
            default=min(2, host.hardware.cpuInfo.numCpuThreads),
            unit="核"
        ))

        print(f"\n主机 {host.name} 可用内存: {host_resources['mem_available_mb']:.1f} MB")
        memory_mb = self.input_memory_with_unit(
            min_val=1024,
            max_val=int(host_resources['mem_available_mb']),
            default=4096
        )

        datastore = self.select_datastore(host)
        if not datastore:
            return

        ds_space = self.get_datastore_space(datastore)
        print(f"\n数据存储 {datastore.name} 可用空间: {ds_space['free_gb']:.1f} GB")
        disk_gb = self.input_with_range(
            "输入磁盘大小",
            20,
            int(ds_space['free_gb']),
            default=20,
            unit="GB"
        )

        network = self.select_network(host)
        if not network:
            return

        resource_pool = self.select_resource_pool(host)
        if not resource_pool:
            return

        folder = self.select_folder(datacenter)
        if not folder:
            return

        print("\n=== 配置确认 ===")
        print(f"虚拟机名称: {vm_name}")
        print(f"操作系统: {guest_id}")
        print(f"CPU核心数: {cpu_count}")
        print(f"内存大小: {memory_mb} MB ({memory_mb / 1024:.1f} GB)")
        print(f"磁盘大小: {disk_gb} GB")
        print(f"主机: {host.name}")
        print(f"数据存储: {datastore.name}")
        print(f"网络: {network.name}")
        print(f"资源池: {resource_pool.name}")
        print(f"文件夹: {folder.name}")

        confirm = input("\n确认创建虚拟机吗？(y/n): ").lower()
        if confirm != 'y':
            print("取消创建虚拟机")
            return

        vm_config = vim.vm.ConfigSpec()
        vm_config.name = vm_name
        vm_config.memoryMB = memory_mb
        vm_config.numCPUs = cpu_count
        vm_config.guestId = guest_id
        vm_config.files = vim.vm.FileInfo()
        vm_config.files.vmPathName = f"[{datastore.name}] {vm_name}/{vm_name}.vmx"

        # 创建SCSI控制器
        scsi_controller = self.create_scsi_controller()

        # 创建磁盘 - 使用控制器key 1000和单元号0
        disk = self.create_virtual_disk(datastore, vm_name, disk_gb,
                                        controller_key=1000, unit_number=0)

        # 创建网络适配器
        nic = self.create_network_adapter(network)

        vm_config.deviceChange = [scsi_controller, disk, nic]

        try:
            print("正在创建虚拟机...")
            task = folder.CreateVM_Task(
                config=vm_config,
                pool=resource_pool,
                host=host
            )

            while task.info.state not in [vim.TaskInfo.State.success, vim.TaskInfo.State.error]:
                pass

            if task.info.state == vim.TaskInfo.State.success:
                vm = task.info.result
                self.selected_vm = vm  # 现在可以设置selected_vm了
                print(f"成功创建虚拟机: {vm.name}")
                print(f"MOID: {vm._moId}")
            else:
                print(f"创建失败: {task.info.error}")
        except Exception as e:
            print(f"创建过程中出错: {str(e)}")

    def modify_vm_config(self):
        """修改虚拟机配置主菜单"""
        while True:
            print("\n=== 修改虚拟机配置 ===")
            print("1. 修改CPU配置")
            print("2. 修改内存配置")
            print("3. 修改网络配置")
            print("0. 返回主菜单")

            try:
                choice = int(input("请选择: "))
                if choice == 1:
                    self.modify_vm_cpu()
                elif choice == 2:
                    self.modify_vm_memory()
                elif choice == 3:
                    self.modify_vm_network()
                elif choice == 0:
                    break
                else:
                    print("无效选择")
            except ValueError:
                print("请输入数字")

    def modify_vm_cpu(self):
        """修改虚拟机CPU配置"""
        print("\n=== 修改CPU配置 ===")

        datacenter = self.select_datacenter()
        if not datacenter:
            return

        vm = self.select_vm(datacenter)
        if not vm:
            return

        print(f"\n当前CPU配置: {vm.config.hardware.numCPU} vCPU")

        # 获取虚拟机所在主机的资源信息
        host = vm.runtime.host
        host_resources = self.get_host_resources(host)

        # 修改CPU配置
        print(f"\n主机 {host.name} 可用CPU核心: {host_resources['cpu_available']:.1f}")
        new_cpu = int(self.input_with_range(
            "输入新的CPU核心数",
            1,
            host.hardware.cpuInfo.numCpuThreads,
            default=vm.config.hardware.numCPU,
            unit="核"
        ))

        # 确认修改
        print("\n=== 修改确认 ===")
        print(f"原CPU: {vm.config.hardware.numCPU} vCPU")
        print(f"新CPU: {new_cpu} vCPU")

        confirm = input("\n确认修改CPU配置吗？(y/n): ").lower()
        if confirm != 'y':
            print("取消修改")
            return

        # 执行修改
        spec = vim.vm.ConfigSpec()
        spec.numCPUs = new_cpu

        try:
            print("正在修改CPU配置...")
            task = vm.ReconfigVM_Task(spec=spec)

            while task.info.state not in [vim.TaskInfo.State.success, vim.TaskInfo.State.error]:
                pass

            if task.info.state == vim.TaskInfo.State.success:
                print("CPU配置修改成功")
            else:
                print(f"修改失败: {task.info.error}")
        except Exception as e:
            print(f"修改过程中出错: {str(e)}")

    def modify_vm_memory(self):
        """修改虚拟机内存配置"""
        print("\n=== 修改内存配置 ===")

        datacenter = self.select_datacenter()
        if not datacenter:
            return

        vm = self.select_vm(datacenter)
        if not vm:
            return

        print(f"\n当前内存配置: {vm.config.hardware.memoryMB} MB ({vm.config.hardware.memoryMB / 1024:.1f} GB)")

        # 获取虚拟机所在主机的资源信息
        host = vm.runtime.host
        host_resources = self.get_host_resources(host)

        # 修改内存配置
        print(f"\n主机 {host.name} 可用内存: {host_resources['mem_available_mb']:.1f} MB")
        new_memory = self.input_memory_with_unit(
            min_val=1024,
            max_val=int(host_resources['mem_available_mb']),
            default=vm.config.hardware.memoryMB
        )

        # 确认修改
        print("\n=== 修改确认 ===")
        print(f"原内存: {vm.config.hardware.memoryMB} MB ({vm.config.hardware.memoryMB / 1024:.1f} GB)")
        print(f"新内存: {new_memory} MB ({new_memory / 1024:.1f} GB)")

        confirm = input("\n确认修改内存配置吗？(y/n): ").lower()
        if confirm != 'y':
            print("取消修改")
            return

        # 执行修改
        spec = vim.vm.ConfigSpec()
        spec.memoryMB = new_memory

        try:
            print("正在修改内存配置...")
            task = vm.ReconfigVM_Task(spec=spec)

            while task.info.state not in [vim.TaskInfo.State.success, vim.TaskInfo.State.error]:
                pass

            if task.info.state == vim.TaskInfo.State.success:
                print("内存配置修改成功")
            else:
                print(f"修改失败: {task.info.error}")
        except Exception as e:
            print(f"修改过程中出错: {str(e)}")

    def modify_vm_network(self):
        """修改虚拟机网络配置"""
        print("\n=== 修改网络配置 ===")

        # 1. 选择虚拟机
        datacenter = self.select_datacenter()
        if not datacenter:
            return

        vm = self.select_vm(datacenter)
        if not vm:
            return

        # 2. 检查虚拟机状态
        if vm.runtime.powerState != 'poweredOff':
            print("警告: 虚拟机需要关机状态才能修改网络配置!")
            confirm = input("是否继续? (y/n): ").lower()
            if confirm != 'y':
                return

        # 3. 获取当前网络适配器
        nics = [dev for dev in vm.config.hardware.device
                if isinstance(dev, vim.vm.device.VirtualEthernetCard)]

        if not nics:
            print("该虚拟机没有网络适配器")
            return

        # 4. 选择要修改的网卡
        print("\n选择要修改的网络适配器:")
        for i, nic in enumerate(nics, 1):
            print(f"{i}. {nic.deviceInfo.label} (当前连接: {nic.deviceInfo.summary})")

        try:
            nic_choice = int(input("请选择: ")) - 1
            if nic_choice < 0 or nic_choice >= len(nics):
                print("无效选择")
                return
        except ValueError:
            print("请输入数字")
            return

        selected_nic = nics[nic_choice]

        # 5. 获取主机信息
        host = vm.runtime.host

        # 6. 选择新网络
        print("\n选择新的网络:")
        network = self.select_network(host)
        if not network:
            return

        # 7. 创建网络配置变更
        nic_spec = vim.vm.device.VirtualDeviceSpec()
        nic_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.edit
        nic_spec.device = selected_nic

        # 更新网络连接
        if isinstance(network, vim.Network):
            nic_spec.device.backing = vim.vm.device.VirtualEthernetCard.NetworkBackingInfo()
            nic_spec.device.backing.network = network
            nic_spec.device.backing.deviceName = network.name
        elif isinstance(network, vim.dvs.DistributedVirtualPortgroup):
            nic_spec.device.backing = vim.vm.device.VirtualEthernetCard.DistributedVirtualPortBackingInfo()
            nic_spec.device.backing.port = vim.dvs.PPortConnection()
            nic_spec.device.backing.port.portgroupKey = network.key
            nic_spec.device.backing.port.switchUuid = network.config.distributedVirtualSwitch.uuid

        # 8. 确认并执行
        print("\n=== 网络修改确认 ===")
        print(f"虚拟机: {vm.name}")
        print(f"网卡: {selected_nic.deviceInfo.label}")
        print(f"原网络: {selected_nic.deviceInfo.summary}")
        print(f"新网络: {network.name}")

        confirm = input("\n确认修改网络配置吗？(y/n): ").lower()
        if confirm != 'y':
            print("取消操作")
            return

        try:
            print("正在修改网络配置...")
            spec = vim.vm.ConfigSpec()
            spec.deviceChange = [nic_spec]

            task = vm.ReconfigVM_Task(spec=spec)

            while task.info.state not in [vim.TaskInfo.State.success, vim.TaskInfo.State.error]:
                pass

            if task.info.state == vim.TaskInfo.State.success:
                print("网络配置修改成功")
            else:
                print(f"修改失败: {task.info.error}")
        except Exception as e:
            print(f"修改过程中出错: {str(e)}")

    def add_vm_configuration(self):
        """添加虚拟机配置主菜单"""
        while True:
            print("\n=== 添加虚拟机配置 ===")
            print("1. 添加硬盘")
            print("2. 添加网卡")
            print("0. 返回主菜单")

            try:
                choice = int(input("请选择: "))
                if choice == 1:
                    self.add_vm_disk()
                elif choice == 2:
                    self.add_vm_nic()
                elif choice == 0:
                    break
                else:
                    print("无效选择")
            except ValueError:
                print("请输入数字")

    def add_vm_disk(self):
        """为虚拟机添加硬盘"""
        print("\n=== 添加硬盘 ===")

        # 1. 选择虚拟机
        datacenter = self.select_datacenter()
        if not datacenter:
            return

        vm = self.select_vm(datacenter)
        if not vm:
            return
        self.selected_vm = vm

        # 2. 检查虚拟机状态
        if vm.runtime.powerState != 'poweredOff':
            print("警告: 虚拟机需要关机状态才能添加硬盘!")
            confirm = input("是否继续? (y/n): ").lower()
            if confirm != 'y':
                return

        # 3. 获取主机信息
        host = vm.runtime.host

        # 4. 选择数据存储
        datastore = self.select_datastore(host)
        if not datastore:
            return

        # 5. 输入磁盘大小
        ds_space = self.get_datastore_space(datastore)
        print(f"\n数据存储 {datastore.name} 可用空间: {ds_space['free_gb']:.1f} GB")

        disk_size = self.input_with_range(
            "输入新磁盘大小(GB)",
            1,  # 最小1GB
            int(ds_space['free_gb']),
            default=20,
            unit="GB"
        )

        # 6. 获取SCSI控制器
        try:
            controller_key = self.get_disk_controller(vm)
        except Exception as e:
            print(f"获取SCSI控制器失败: {str(e)}")
            print("将尝试使用默认控制器key 1000")
            controller_key = 1000

        # 7. 获取下一个可用单元号
        try:
            unit_number = self.get_next_unit_number(vm)
        except Exception as e:
            print(f"获取可用单元号失败: {str(e)}")
            print("将尝试使用默认单元号0")
            unit_number = 0

        # 8. 创建磁盘配置
        try:
            disk_spec = self.create_virtual_disk(
                datastore=datastore,
                vm_name=vm.name,
                size_gb=disk_size,
                controller_key=controller_key,
                unit_number=unit_number
            )
        except Exception as e:
            print(f"创建磁盘配置失败: {str(e)}")
            return

        # 9. 确认并执行
        print("\n=== 添加磁盘确认 ===")
        print(f"虚拟机: {vm.name}")
        print(f"磁盘大小: {disk_size} GB")
        print(f"数据存储: {datastore.name}")
        print(f"控制器key: {controller_key}")
        print(f"单元号: {unit_number}")

        confirm = input("\n确认添加磁盘吗？(y/n): ").lower()
        if confirm != 'y':
            print("取消操作")
            return

        try:
            print("正在添加磁盘...")
            spec = vim.vm.ConfigSpec()
            spec.deviceChange = [disk_spec]

            task = vm.ReconfigVM_Task(spec=spec)

            while task.info.state not in [vim.TaskInfo.State.success, vim.TaskInfo.State.error]:
                pass

            if task.info.state == vim.TaskInfo.State.success:
                print("磁盘添加成功")
            else:
                print(f"添加失败: {task.info.error}")
        except Exception as e:
            print(f"添加过程中出错: {str(e)}")

    def add_vm_nic(self):
        """为虚拟机添加网卡"""
        print("\n=== 添加网卡 ===")

        # 1. 选择虚拟机
        datacenter = self.select_datacenter()
        if not datacenter:
            return

        vm = self.select_vm(datacenter)
        if not vm:
            return
        self.selected_vm = vm

        # 2. 检查虚拟机状态
        if vm.runtime.powerState != 'poweredOff':
            print("警告: 虚拟机需要关机状态才能添加网卡!")
            confirm = input("是否继续? (y/n): ").lower()
            if confirm != 'y':
                return

        # 3. 获取主机信息
        host = vm.runtime.host

        # 4. 选择网络
        network = self.select_network(host)
        if not network:
            return

        # 5. 创建网卡配置
        nic_spec = self.create_network_adapter(network)

        # 6. 确认并执行
        print("\n=== 添加网卡确认 ===")
        print(f"虚拟机: {vm.name}")
        print(f"网络: {network.name}")

        confirm = input("\n确认添加网卡吗？(y/n): ").lower()
        if confirm != 'y':
            print("取消操作")
            return

        try:
            print("正在添加网卡...")
            spec = vim.vm.ConfigSpec()
            spec.deviceChange = [nic_spec]

            task = vm.ReconfigVM_Task(spec=spec)

            while task.info.state not in [vim.TaskInfo.State.success, vim.TaskInfo.State.error]:
                pass

            if task.info.state == vim.TaskInfo.State.success:
                print("网卡添加成功")
            else:
                print(f"添加失败: {task.info.error}")
        except Exception as e:
            print(f"添加过程中出错: {str(e)}")

    def remove_vm_configuration(self):
        """删除虚拟机配置主菜单"""
        while True:
            print("\n=== 删除虚拟机配置 ===")
            print("1. 删除硬盘")
            print("2. 删除网卡")
            print("0. 返回主菜单")

            try:
                choice = int(input("请选择: "))
                if choice == 1:
                    self.remove_vm_disk()
                elif choice == 2:
                    self.remove_vm_nic()
                elif choice == 0:
                    break
                else:
                    print("无效选择")
            except ValueError:
                print("请输入数字")

    def remove_vm_disk(self):
        """删除虚拟机硬盘"""
        print("\n=== 删除硬盘 ===")

        # 1. 选择虚拟机
        datacenter = self.select_datacenter()
        if not datacenter:
            return

        vm = self.select_vm(datacenter)
        if not vm:
            return
        self.selected_vm = vm

        # 2. 检查虚拟机状态
        if vm.runtime.powerState != 'poweredOff':
            print("警告: 虚拟机需要关机状态才能删除硬盘!")
            confirm = input("是否继续? (y/n): ").lower()
            if confirm != 'y':
                return

        # 3. 获取所有硬盘设备
        disks = [dev for dev in vm.config.hardware.device
                if isinstance(dev, vim.vm.device.VirtualDisk)]

        if not disks:
            print("该虚拟机没有可删除的硬盘")
            return

        # 4. 显示硬盘列表供选择
        print("\n选择要删除的硬盘:")
        for i, disk in enumerate(disks, 1):
            disk_size = disk.capacityInKB / (1024 * 1024)  # 转换为GB
            print(f"{i}. {disk.deviceInfo.label} - {disk_size:.1f} GB")

        try:
            disk_choice = int(input("请选择要删除的硬盘: ")) - 1
            if disk_choice < 0 or disk_choice >= len(disks):
                print("无效选择")
                return
        except ValueError:
            print("请输入数字")
            return

        selected_disk = disks[disk_choice]

        # 5. 确认删除
        print("\n=== 删除确认 ===")
        print(f"虚拟机: {vm.name}")
        print(f"硬盘: {selected_disk.deviceInfo.label}")
        print(f"大小: {selected_disk.capacityInKB / (1024 * 1024):.1f} GB")
        print(f"文件名: {selected_disk.backing.fileName}")

        confirm = input("\n确认删除此硬盘吗？此操作不可恢复！(y/n): ").lower()
        if confirm != 'y':
            print("取消操作")
            return

        # 6. 创建删除配置
        disk_spec = vim.vm.device.VirtualDeviceSpec()
        disk_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.remove
        disk_spec.device = selected_disk
        disk_spec.fileOperation = vim.vm.device.VirtualDeviceSpec.FileOperation.destroy

        # 7. 执行删除
        try:
            print("正在删除硬盘...")
            spec = vim.vm.ConfigSpec()
            spec.deviceChange = [disk_spec]

            task = vm.ReconfigVM_Task(spec=spec)

            while task.info.state not in [vim.TaskInfo.State.success, vim.TaskInfo.State.error]:
                pass

            if task.info.state == vim.TaskInfo.State.success:
                print("硬盘删除成功")
            else:
                print(f"删除失败: {task.info.error}")
        except Exception as e:
            print(f"删除过程中出错: {str(e)}")

    def remove_vm_nic(self):
        """删除虚拟机网卡"""
        print("\n=== 删除网卡 ===")

        # 1. 选择虚拟机
        datacenter = self.select_datacenter()
        if not datacenter:
            return

        vm = self.select_vm(datacenter)
        if not vm:
            return
        self.selected_vm = vm

        # 2. 检查虚拟机状态
        if vm.runtime.powerState != 'poweredOff':
            print("警告: 虚拟机需要关机状态才能删除网卡!")
            confirm = input("是否继续? (y/n): ").lower()
            if confirm != 'y':
                return

        # 3. 获取所有网卡设备
        nics = [dev for dev in vm.config.hardware.device
               if isinstance(dev, vim.vm.device.VirtualEthernetCard)]

        if len(nics) <= 1:
            print("该虚拟机只有一张网卡，不能删除")
            return

        # 4. 显示网卡列表供选择
        print("\n选择要删除的网卡:")
        for i, nic in enumerate(nics, 1):
            print(f"{i}. {nic.deviceInfo.label} - {nic.deviceInfo.summary}")

        try:
            nic_choice = int(input("请选择要删除的网卡: ")) - 1
            if nic_choice < 0 or nic_choice >= len(nics):
                print("无效选择")
                return
        except ValueError:
            print("请输入数字")
            return

        selected_nic = nics[nic_choice]

        # 5. 确认删除
        print("\n=== 删除确认 ===")
        print(f"虚拟机: {vm.name}")
        print(f"网卡: {selected_nic.deviceInfo.label}")
        print(f"当前连接: {selected_nic.deviceInfo.summary}")

        confirm = input("\n确认删除此网卡吗？(y/n): ").lower()
        if confirm != 'y':
            print("取消操作")
            return

        # 6. 创建删除配置
        nic_spec = vim.vm.device.VirtualDeviceSpec()
        nic_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.remove
        nic_spec.device = selected_nic

        # 7. 执行删除
        try:
            print("正在删除网卡...")
            spec = vim.vm.ConfigSpec()
            spec.deviceChange = [nic_spec]

            task = vm.ReconfigVM_Task(spec=spec)

            while task.info.state not in [vim.TaskInfo.State.success, vim.TaskInfo.State.error]:
                pass

            if task.info.state == vim.TaskInfo.State.success:
                print("网卡删除成功")
            else:
                print(f"删除失败: {task.info.error}")
        except Exception as e:
            print(f"删除过程中出错: {str(e)}")

    def manage_vm_power(self):
        """管理虚拟机电源状态（带分页功能，每页10个）"""
        print("\n=== 管理虚拟机电源状态 ===")

        # 1. 选择数据中心
        datacenter = self.select_datacenter()
        if not datacenter:
            return

        # 2. 获取所有虚拟机
        vms = []

        def traverse(folder):
            for child in folder.childEntity:
                if isinstance(child, vim.VirtualMachine):
                    vms.append(child)
                elif isinstance(child, vim.Folder):
                    traverse(child)

        traverse(datacenter.vmFolder)

        if not vms:
            print("没有找到任何虚拟机")
            return

        # 分页显示
        page_size = 10
        total_pages = (len(vms) + page_size - 1) // page_size
        current_page = 1

        while True:
            print(f"\n虚拟机列表 (第 {current_page}/{total_pages} 页):")
            print("=" * 30)

            # 计算当前页的起始和结束索引
            start_idx = (current_page - 1) * page_size
            end_idx = min(start_idx + page_size, len(vms))

            # 显示当前页的虚拟机
            for i in range(start_idx, end_idx):
                print(f"{i + 1}. {vms[i].name}")

            # 分页导航
            print("\n导航:")
            if current_page > 1:
                print("p: 上一页")
            if current_page < total_pages:
                print("n: 下一页")
            print("0: 返回")

            # 用户输入
            choice = input("\n选择虚拟机(输入序号)或导航命令: ").strip().lower()

            # 处理导航命令
            if choice == 'p' and current_page > 1:
                current_page -= 1
                continue
            elif choice == 'n' and current_page < total_pages:
                current_page += 1
                continue
            elif choice == '0':
                return

            # 处理虚拟机选择
            try:
                vm_choice = int(choice) - 1
                if 0 <= vm_choice < len(vms):
                    vm = vms[vm_choice]
                    current_state = vm.runtime.powerState
                    print(f"\n当前选择: {vm.name} ({current_state})")
                    self._handle_vm_power_operations(vm)
                    break
                else:
                    print("无效选择")
            except ValueError:
                print("请输入有效数字或命令")

    def delete_vm(self):
        """删除虚拟机"""
        print("\n=== 删除虚拟机 ===")

        # 1. 选择数据中心
        datacenter = self.select_datacenter()
        if not datacenter:
            return

        # 2. 选择虚拟机
        vm = self.select_vm(datacenter)
        if not vm:
            return

        try:
            # 3. 检查虚拟机状态
            current_state = vm.runtime.powerState
            print(f"\n虚拟机状态: {current_state}")

            if current_state == "poweredOn":
                print("警告: 虚拟机正在运行，需要先关机才能删除!")
                print("\n请选择操作:")
                print("1. 正常关机")
                print("2. 强制关机")
                print("3. 取消删除")

                try:
                    choice = int(input("请选择操作 (1-3): "))
                    if choice == 1:
                        self._shutdown_vm_gracefully(vm)
                    elif choice == 2:
                        self._power_off_vm_hard(vm)
                    elif choice == 3:
                        print("取消删除操作")
                        return
                    else:
                        print("无效选择")
                        return
                except ValueError:
                    print("请输入有效数字")
                    return

                # 检查是否关机成功
                try:
                    if vm.runtime.powerState != "poweredOff":
                        print("虚拟机未能成功关机，删除操作取消")
                        return
                except Exception as e:
                    print(f"无法获取虚拟机状态: {str(e)}")
                    return

            # 4. 确认删除
            vm_name = vm.name  # 先保存虚拟机名称
            print(f"\n即将删除虚拟机: {vm_name}")
            try:
                print(f"所在主机: {vm.runtime.host.name}")
                print(f"数据存储: {vm.datastore[0].name if vm.datastore else '未知'}")
            except Exception as e:
                print(f"获取虚拟机信息时出错: {str(e)}")

            confirm = input("\n确认删除此虚拟机吗？此操作不可恢复！(y/n): ").lower()
            if confirm != 'y':
                print("取消删除操作")
                return

            # 5. 执行删除
            try:
                print("正在删除虚拟机...")
                task = vm.Destroy_Task()

                while task.info.state not in [vim.TaskInfo.State.success, vim.TaskInfo.State.error]:
                    pass

                if task.info.state == vim.TaskInfo.State.success:
                    print(f"虚拟机 {vm_name} 已成功删除")
                else:
                    print(f"删除失败: {task.info.error}")
            except Exception as e:
                if hasattr(e, 'msg') and 'already been deleted' in e.msg:
                    print(f"虚拟机 {vm_name} 已被删除")
                else:
                    print(f"删除过程中出错: {str(e)}")

        except Exception as e:
            if hasattr(e, 'msg') and 'already been deleted' in e.msg:
                print("虚拟机已被删除")
            else:
                print(f"操作过程中出错: {str(e)}")

    def _handle_vm_power_operations(self, vm):
        """处理虚拟机电源操作"""
        current_state = vm.runtime.powerState

        while True:
            print("\n可执行操作:")
            if current_state == "poweredOn":
                print("1. 关机")
                print("2. 重启")
                print("3. 强制关机")
                print("4. 删除虚拟机")
            elif current_state == "poweredOff":
                print("1. 开机")
                print("2. 打开电源并进入BIOS")
                print("3. 删除虚拟机")
            else:
                print(f"未知状态: {current_state}")

            print("0. 返回列表")

            try:
                action = input("请选择操作: ").strip()

                if action == '0':
                    return

                elif current_state == "poweredOn":
                    if action == '1':
                        self._shutdown_vm_gracefully(vm)
                    elif action == '2':
                        self._reboot_vm(vm)
                    elif action == '3':
                        self._power_off_vm_hard(vm)
                    elif action == '4':
                        self.delete_vm()
                        return
                    else:
                        print("无效选择")

                elif current_state == "poweredOff":
                    if action == '1':
                        self._power_on_vm(vm)
                    elif action == '2':
                        self._power_on_to_bios(vm)
                    elif action == '3':
                        self.delete_vm()
                        return
                    else:
                        print("无效选择")

                # 更新状态
                current_state = vm.runtime.powerState
                print(f"\n当前状态: {current_state}")

            except Exception as e:
                print(f"操作失败: {str(e)}")

    def _power_on_vm(self, vm):
        """正常开机"""
        print(f"正在启动 {vm.name}...")
        task = vm.PowerOnVM_Task()
        self._wait_for_task(task)

    def _power_on_to_bios(self, vm):
        """开机进入BIOS"""
        print(f"启动 {vm.name} 到BIOS...")
        spec = vim.vm.ConfigSpec()
        spec.bootOptions = vim.vm.BootOptions(enterBIOSSetup=True)
        vm.ReconfigVM_Task(spec=spec)
        self._power_on_vm(vm)

    def _shutdown_vm_gracefully(self, vm):
        """正常关机（通过VMware Tools）"""
        if vm.guest.toolsStatus == "toolsOk":
            print(f"正在正常关闭 {vm.name}...")
            vm.ShutdownGuest()
        else:
            print("VMware Tools不可用，改为强制关机")
            self._power_off_vm_hard(vm)

    def _reboot_vm(self, vm):
        """重启虚拟机"""
        if vm.guest.toolsStatus == "toolsOk":
            print(f"正在重启 {vm.name}...")
            vm.RebootGuest()
        else:
            print("VMware Tools不可用，改为强制重启")
            self._reset_vm(vm)

    def _power_off_vm_hard(self, vm):
        """强制关机"""
        print(f"强制关闭 {vm.name}...")
        task = vm.PowerOffVM_Task()
        self._wait_for_task(task)

    def _reset_vm(self, vm):
        """强制重启"""
        print(f"强制重启 {vm.name}...")
        task = vm.ResetVM_Task()
        self._wait_for_task(task)

    def _wait_for_task(self, task):
        """等待任务完成"""
        while task.info.state not in [vim.TaskInfo.State.success, vim.TaskInfo.State.error]:
            pass
        if task.info.state == vim.TaskInfo.State.success:
            print("操作成功完成")
        else:
            print(f"操作失败: {task.info.error}")


def main():
    manager = VCenterManager()
    config_file = Path("vcenter_config.json")

    # 尝试加载保存的配置
    saved_config = None
    if config_file.exists():
        try:
            with open(config_file, 'r') as f:
                saved_config = json.load(f)
            print("\n已保存的vCenter配置:")
            print(f"主机: {saved_config['host']}")
            print(f"账户: {saved_config['user']}")
            use_saved = input("是否使用这些配置? (y/n): ").lower() == 'y'
            if use_saved:
                vcenter_host = saved_config['host']
                vcenter_user = saved_config['user']
                vcenter_password = saved_config['password']
                # 使用保存的配置，不再询问是否保存
                save_config = False
            else:
                # 用户选择手动输入，后续会询问是否保存
                vcenter_host = input("主机: ")
                vcenter_user = input("账户: ")
                vcenter_password = input("密码: ")
                save_config = True
        except Exception as e:
            vcenter_host = input("主机: ")
            vcenter_user = input("账户: ")
            vcenter_password = input("密码: ")
            save_config = True
    else:
        # 没有保存的配置，手动输入并询问是否保存
        vcenter_host = input("主机: ")
        vcenter_user = input("账户: ")
        vcenter_password = input("密码: ")
        save_config = True

    # 如果是新配置，询问是否保存
    if save_config:
        save_config = input("是否保存这些登录信息以便下次使用? (y/n): ").lower() == 'y'
        if save_config:
            try:
                with open(config_file, 'w') as f:
                    json.dump({
                        'host': vcenter_host,
                        'user': vcenter_user,
                        'password': vcenter_password
                    }, f)
                print("配置已保存")
            except Exception as e:
                print(f"保存配置失败: {e}")

    if not manager.connect(vcenter_host, vcenter_user, vcenter_password):
        return

    while True:
        print("\n=== vCenter 管理工具 ===")
        print("1. 创建虚拟机")
        print("2. 修改虚拟机配置")
        print("3. 添加虚拟机配置")
        print("4. 删除虚拟机配置")
        print("5. 管理虚拟机电源状态")
        print("6. 删除虚拟机")
        print("7. 更改登录信息")
        print("0. 退出")

        try:
            choice = int(input("请选择: "))
            if choice == 1:
                manager.create_vm_interactive()
            elif choice == 2:
                manager.modify_vm_config()
            elif choice == 3:
                manager.add_vm_configuration()
            elif choice == 4:
                manager.remove_vm_configuration()
            elif choice == 5:
                manager.manage_vm_power()
            elif choice == 6:
                manager.delete_vm()
            elif choice == 7:
                # 更改登录信息
                if config_file.exists():
                    os.remove(config_file)
                    print("已清除保存的登录信息")
                return main()  # 重新开始
            elif choice == 0:
                print("再见！")
                break
            else:
                print("无效选择")
        except ValueError:
            print("请输入数字")


if __name__ == "__main__":
    main()